package org.qydjk.console.controller.wechatPublicNumber;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.qydjk.common.controller.BaseController;
import org.qydjk.common.pojo.WechatPublicMenu;
import org.qydjk.common.util.BeanUtil;
import org.qydjk.common.util.RedisTemplateUtil;
import org.qydjk.common.util.StringUtil;
import org.qydjk.common.util.wechat.WechatUtil;
import org.qydjk.common.vo.Tree;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;

/**
 * Created by Lanan on 2017/12/26 0026.
 */

@Controller
@RequestMapping("/wechat/public/number/menu")
public class WechatPublicNumberMenuController extends BaseController {
    @Autowired
    private RedisTemplateUtil redisTemplateUtil;

    @RequestMapping("/index.do")
    public String wechatPublicNumberMenuIndex() {
        return "/wechatPublicNumber/menu/wechatPublicNumberMenu";
    }

    @RequestMapping("/list.do")
    @ResponseBody
    public Object wechatPublicNumberMenuList() {
        String sql = "SELECT * FROM qy_wechat_public_menu";
        try {
            List<WechatPublicMenu> wechatPublicMenus = baseService.findBySQL(sql, WechatPublicMenu.class);
            return wechatPublicMenus;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 插入页面
     * @return
     */
    @RequestMapping("/insert/index.do")
    public String wechatPublicNumberMenuInsertIndex() {
        handleMenuDataToJsonString();
        return "/wechatPublicNumber/menu/wechatPublicNumberMenuInsert";
    }

    /**
     * 插入处理
     * @param wechatPublicMenu
     * @return
     */
    @RequestMapping("/insert.do")
    @ResponseBody
    public Object wechatPublicNumberMenuInsert(WechatPublicMenu wechatPublicMenu) {
        wechatPublicMenu.setCreateTime(new Date());
        wechatPublicMenu.setOrd(0);
        return hanleInsertOrUpdate(true, wechatPublicMenu);
    }

    /**
     * 修改页面
     * @return
     */
    @RequestMapping("/update/index.do")
    public String wechatPublicNumberMenuUpdateIndex() {
        Integer id = Integer.valueOf(request.getParameter("id"));
        try {
            WechatPublicMenu wechatPublicMenu = baseService.get(WechatPublicMenu.class, id.intValue());
            request.setAttribute("menu", wechatPublicMenu);
            return "/wechatPublicNumber/menu/wechatPublicNumberMenuUpdate";
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 修改处理
     * @param wechatPublicMenu
     * @return
     */
    @RequestMapping("/update.do")
    @ResponseBody
    public Object wechatPublicNumberMenuUpdate(WechatPublicMenu wechatPublicMenu) {
        return hanleInsertOrUpdate(false, wechatPublicMenu);
    }

    /**
     * 添加和修改集中处理方法
     * @param isInsert
     * @param wechatPublicMenu
     * @return
     */
    private Object hanleInsertOrUpdate(boolean isInsert, WechatPublicMenu wechatPublicMenu) {
        wechatPublicMenu.setUpdateTime(new Date());
        JSONObject resp = new JSONObject();
        try {
            WechatPublicMenu oldWPM = new WechatPublicMenu();
            if (!isInsert) {
                oldWPM = baseService.get(WechatPublicMenu.class, wechatPublicMenu.getId());
            }
            // 当操作的是一级菜单
            if (wechatPublicMenu.getParentid() == null) {
                String type = wechatPublicMenu.getType();
                Integer subCount = 0;
                if (!isInsert) {
                    String sqlSub = "SELECT COUNT(id) FROM qy_wechat_public_menu WHERE parentid = " + wechatPublicMenu.getId();
                    subCount = baseService.getRecordCountSQL(sqlSub);
                }
                if (subCount > 0) {
                    if ("view".equals(type)
                            || "click".equals(type)
                            || "miniprogram".equals(type)
                            || "location_select".equals(type)
                            || "media_id".equals(type)
                            || "view_limited".equals(type)) {
                        resp.put("success", false);
                        resp.put("msg", "该菜单因含子菜单不可修改为该菜单类型!");
                        return JSON.toJSON(resp);
                    }
                }
                String sql = "SELECT COUNT(id) FROM qy_wechat_public_menu WHERE parentid is " + null;
                Integer count = baseService.getRecordCountSQL(sql);
                if (count >= 3) {
                    resp.put("success", false);
                    resp.put("msg", "最多只能设置3个主菜单!");
                    if (!isInsert) {
                        if (oldWPM.getParentid() != wechatPublicMenu.getParentid()) {
                            return JSON.toJSON(resp);
                        }
                    } else {
                        return JSON.toJSON(resp);
                    }
                }
                // 当操作的是二级菜单
            } else {
                if (wechatPublicMenu.getParentid() == wechatPublicMenu.getId()) {
                    resp.put("success", false);
                    resp.put("msg", "菜单不能设置自己为自己的子菜单!");
                    return JSON.toJSON(resp);
                }
                Integer subCount = 0;
                if (!isInsert) {
                    String sqlSub = "SELECT COUNT(id) FROM qy_wechat_public_menu WHERE parentid = " + wechatPublicMenu.getId();
                    subCount = baseService.getRecordCountSQL(sqlSub);
                }
                if (subCount > 0) {
                    resp.put("success", false);
                    resp.put("msg", "该菜单因含子菜单不可修改为二级菜单!");
                    return JSON.toJSON(resp);
                }

                if (StringUtil.isEmptyOrNull(wechatPublicMenu.getType())) {
                    resp.put("success", false);
                    resp.put("msg", "该菜单类型不可设置为子菜单!");
                    return JSON.toJSON(resp);
                }
                String sql = "SELECT COUNT(id) FROM qy_wechat_public_menu WHERE parentid = " + wechatPublicMenu.getParentid();
                Integer count = baseService.getRecordCountSQL(sql);
                if (count >= 5) {
                    resp.put("success", false);
                    resp.put("msg", "每个主菜单下最多只能设置5个子菜单!");
                    if (!isInsert) {
                        if (oldWPM.getParentid() != wechatPublicMenu.getParentid()) {
                            return JSON.toJSON(resp);
                        }
                    } else {
                        return JSON.toJSON(resp);
                    }
                }
            }
            dataHandelInsertOrUpdate(wechatPublicMenu, wechatPublicMenu.getType());
            if (isInsert) {
                return insertNewInfo(resp, wechatPublicMenu);
            } else {
               return updateNewInfo(resp, wechatPublicMenu, oldWPM);
            }
        } catch (Exception e) {
            e.printStackTrace();
            resp.put("success", false);
            resp.put("msg", e.toString());
        }
        return JSON.toJSON(resp);
    }

    /**
     * 处理预存数据
     * @param wechatPublicMenu
     * @param type
     * @return 处理结果
     */
    private void dataHandelInsertOrUpdate(WechatPublicMenu wechatPublicMenu, String type) {
        if (StringUtil.isEmptyOrNull(type)) {  // 无类型
            wechatPublicMenu.setK(null);
            wechatPublicMenu.setMediaId(null);
            wechatPublicMenu.setUrl(null);
            wechatPublicMenu.setAppid(null);
            wechatPublicMenu.setPagepath(null);
            wechatPublicMenu.setParentid(null);
        } else if ("view".equals(type)) {  // 页面
            wechatPublicMenu.setK(null);
            wechatPublicMenu.setMediaId(null);
            wechatPublicMenu.setAppid(null);
            wechatPublicMenu.setPagepath(null);
        } else if ("click".equals(type) ||   /* 按钮 */
                "scancode_waitmsg".equals(type) ||  /* 扫码提示 */
                "scancode_push".equals(type) || /* 扫码推事件 */
                "pic_sysphoto".equals(type) || /* 系统拍照发图 */
                "pic_photo_or_album".equals(type) || /* 拍照或者相册发图 */
                "pic_weixin".equals(type) || /* 微信相册发图 */
                "location_select".equals(type) /* 发送位置 */ ) {
            wechatPublicMenu.setMediaId(null);
            wechatPublicMenu.setUrl(null);
            wechatPublicMenu.setAppid(null);
            wechatPublicMenu.setPagepath(null);
        } else if ("miniprogram".equals(type)) {  // 小程序
            wechatPublicMenu.setK(null);
            wechatPublicMenu.setMediaId(null);
        } else if ("media_id".equals(type) || "view_limited".equals(type)) {  // 图片 ||  图文消息
            wechatPublicMenu.setK(null);
            wechatPublicMenu.setUrl(null);
            wechatPublicMenu.setAppid(null);
            wechatPublicMenu.setPagepath(null);
        }
    }

    /**
     * 插入
     * @param resp
     * @param wechatPublicMenu
     * @return
     */
    private Object insertNewInfo(JSONObject resp, WechatPublicMenu wechatPublicMenu) {
        try {
            baseService.save(wechatPublicMenu);
            resp.put("success", true);
            resp.put("msg", "添加");
        } catch (Exception e) {
            resp.put("success", false);
            resp.put("msg", e.toString());
        }
        return JSON.toJSON(resp);
    }

    /**
     * 修改
     * @param resp
     * @param wechatPublicMenu
     * @param oldWPM
     * @return
     */
    private Object updateNewInfo(JSONObject resp, WechatPublicMenu wechatPublicMenu, WechatPublicMenu oldWPM) {
        try {
            BeanUtil.copyProperties(wechatPublicMenu, oldWPM);
            dataHandelInsertOrUpdate(oldWPM, wechatPublicMenu.getType());
            baseService.update(oldWPM);
            resp.put("success", true);
            resp.put("msg", "修改");
        } catch (Exception e) {
            e.printStackTrace();
            resp.put("success", false);
            resp.put("msg", e.toString());
        }
        return JSON.toJSON(resp);
    }

    /**
     * 删除
     * @param wechatPublicMenu
     * @return
     */
    @RequestMapping("/delete.do")
    @ResponseBody
    public Object wechatPublicNumberMenuDelete(WechatPublicMenu wechatPublicMenu) {
        JSONObject resp = new JSONObject();
        try {
            WechatPublicMenu oldWPM = baseService.get(WechatPublicMenu.class, wechatPublicMenu.getId().intValue());
            if (oldWPM.getParentid() == null) {
                String sqlSub = "SELECT COUNT(id) FROM qy_wechat_public_menu WHERE parentid = " + wechatPublicMenu.getId();
                Integer subCount = baseService.getRecordCountSQL(sqlSub);
                if (subCount > 0) {
                    resp.put("success", false);
                    resp.put("msg", "该菜单含有子菜单,删除失败!");
                    return JSON.toJSON(resp);
                }
                return handelDelete(resp, oldWPM);
            }
            return handelDelete(resp, oldWPM);
        } catch (Exception e) {
            e.printStackTrace();
            resp.put("success", false);
            resp.put("msg", e.toString());
        }
        return JSON.toJSON(resp);
    }

    private Object handelDelete(JSONObject resp, WechatPublicMenu wechatPublicMenu) {
        try {
            resp.put("success", true);
            baseService.delete(wechatPublicMenu);
        } catch (Exception e) {
            e.printStackTrace();
            resp.put("success", false);
            resp.put("msg", e.toString());

        }
        return JSON.toJSON(resp);
    }

    /**
     * 添加或编辑时的树的选择
     * @return
     */
    @RequestMapping("/tree.do")
    @ResponseBody
    public Object getWechatPublicNumberMenuTree() {
        String sql = "SELECT * FROM qy_wechat_public_menu WHERE parentid is " + null + " " +
                "AND type != 'view' " +
                "AND type != 'click' " +
                "AND type != 'miniprogram' " +
                "AND type != 'location_select' " +
                "AND type != 'media_id' " +
                "AND type != 'view_limited' " +
                "ORDER BY ord DESC";
        try {
            List<WechatPublicMenu> list = baseService.findBySQL(sql, WechatPublicMenu.class);
            return buildArticleTree(list);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 刷新公众号菜单
     */
    @RequestMapping("/update/menu.do")
    @ResponseBody
    public Object updateWechatPublicNumberMenu() {
        JSONObject resp = new JSONObject();
        try {
            String json = handleMenuDataToJsonString();
            System.out.println(json);
            WechatUtil.genMenu(redisTemplateUtil, json);
            resp.put("success", true);
            resp.put("msg", "同步成功");
        } catch (Exception e) {
            e.printStackTrace();
            resp.put("success", false);
            resp.put("msg", e.toString());
        }
        return JSON.toJSON(resp);
    }


    /* ------------------------------------------------- 逻辑处理部分 ---------------------------------------------------- */

    /**
     * 构建树
     * @param wechatPublicMenus
     * @return
     */
    private List<Tree> buildArticleTree(List<WechatPublicMenu> wechatPublicMenus) {
        try {
            List<Tree> trees = new ArrayList<Tree>();
            for (WechatPublicMenu wechatPublicMenu : wechatPublicMenus) {
                Tree articTree = new Tree();
                articTree.setId(wechatPublicMenu.getId());
                articTree.setPid(wechatPublicMenu.getParentid());
                articTree.setText(wechatPublicMenu.getName());
                trees.add(articTree);
            }
            return trees;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将数据改变成json字符串
     */
    public String handleMenuDataToJsonString() {
        Map<String, Object> map = new HashMap<String, Object>();
        List<Object> list = new ArrayList<Object>();
        try {
            String sqlFirst = "SELECT * FROM qy_wechat_public_menu WHERE parentid is " + null + " ORDER BY ord DESC";
            List<WechatPublicMenu> wechatPublicMenus = baseService.findBySQL(sqlFirst, WechatPublicMenu.class);
            for (WechatPublicMenu wechatPublicMenu: wechatPublicMenus) {
                String type = wechatPublicMenu.getType();
                // 不可设置subButton
                if ("view".equals(type)
                        || "click".equals(type)
                        || "miniprogram".equals(type)
                        || "location_select".equals(type)
                        || "media_id".equals(type)
                        || "view_limited".equals(type)) {
                    // 将处理结果装入数组
                    list.add(canntSetSubMenu(wechatPublicMenu));
                } else {
                    // 可设置subButton
                    String sqlSecond = "SELECT * FROM qy_wechat_public_menu WHERE parentid = " + wechatPublicMenu.getId() + " ORDER BY ord DESC";
                    List<WechatPublicMenu> subWechatPublicMenus = baseService.findBySQL(sqlSecond, WechatPublicMenu.class);
                    // 将处理结果加入数组
                    list.add(canSetSubMenu(wechatPublicMenu, subWechatPublicMenus));
                }
            }
            // 处理结束 将map 转为json 字符串
            try {
                map.put("button", list);
                ObjectMapper mapper = new ObjectMapper();
                String json = mapper.writeValueAsString(map);
                return json;
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    private Map canSetSubMenu(WechatPublicMenu wechatPublicMenu, List subWechatPublicMenus) {
        String type = wechatPublicMenu.getType();
        Map<String, Object> tempMap = new HashMap<String, Object>();
        tempMap.put("type", type);
        tempMap.put("name", wechatPublicMenu.getName());
        if (!StringUtil.isEmptyOrNull(type)) {
            tempMap.put("key", wechatPublicMenu.getK());
        }
        if (subWechatPublicMenus.size() > 0) {
            tempMap.put("sub_button", handelSubButton(subWechatPublicMenus));
        }
        return tempMap;
    }

    private List<Object> handelSubButton(List<WechatPublicMenu> subWechatPublicMenus)  {
        List<Object> list = new ArrayList<Object>();
        for (WechatPublicMenu wechatPublicMenu: subWechatPublicMenus) {
            String type = wechatPublicMenu.getType();
            if ("view".equals(type)
                    || "click".equals(type)
                    || "miniprogram".equals(type)
                    || "location_select".equals(type)
                    || "media_id".equals(type)
                    || "view_limited".equals(type)) {
                // 将处理结果装入数组
                list.add(canntSetSubMenu(wechatPublicMenu));
            } else {
                Map<String, Object> tempMap = new HashMap<String, Object>();
                tempMap.put("type", type);
                tempMap.put("name", wechatPublicMenu.getName());
                tempMap.put("key", wechatPublicMenu.getK());
//                tempMap.put("sub_button", new ArrayList<Object>());
                list.add(tempMap);
            }
        }
        return list;
    }

    /**
     * 处理不可设置子菜单项
     * @param wechatPublicMenu
     * @return
     */
    private Map canntSetSubMenu(WechatPublicMenu wechatPublicMenu) {
        String type = wechatPublicMenu.getType();
        Map<String, Object> tempMap = new HashMap<String, Object>();
        tempMap.put("type", type);
        tempMap.put("name", wechatPublicMenu.getName());
        if ("view".equals(type)) {  // 链接跳转
            tempMap.put("url", wechatPublicMenu.getUrl());
        } else if ("click".equals(type) || "location_select".equals(type)) { // 按钮 || 发送位置
            tempMap.put("key", wechatPublicMenu.getK());
        } else if ("miniprogram".equals(type)) { // 小程序
            tempMap.put("url", wechatPublicMenu.getUrl());
            tempMap.put("appid", wechatPublicMenu.getAppid());
            tempMap.put("pagepath", wechatPublicMenu.getPagepath());
        } else if ("media_id".equals(type) || "view_limited".equals(type)) { // 图片 || 图文消息
            tempMap.put("media_id", wechatPublicMenu.getMediaId());
        }
        return tempMap;
    }

}
